#include "ReferenceCountingInterface.h"
#include "Locking.h"

template <typename T>
class RefCountingTraits
{
public:
	static void Refer(T* p)
	{
		p->IncRef();
	}
	static void Unrefer(T* p)
	{
		p->DecRef();
	}
};

//*Sepcialize
template <>
class RefCountingTraits<Shape::HierarchyId>
{
public:
	static void Refer(Shape* p)
	{
		p->IncRef();
	}
	static void Unrefer(Shape* p)
	{
		cout << "RefCountingTraits<Shape::HierarchyId>" << endl;
		p->DecRef();
	}
};

//*Specialize
template <>
class RefCountingTraits<Bitmap::HierarchyId>
{
public:
	static void Refer(Bitmap* p)
	{
		p->IncRef();
	}
	static void Unrefer(Bitmap* p)
	{
		cout << "RefCountingTraits<Bitmap::HierarchyId>" << endl;
		p->DecRef();
	}
};

//*Specialize
template <>
class RefCountingTraits<Widget::HierarchyId>
{
public:
	static void Refer(Widget* p)
	{
		p->AddReference();
	}
	static void Unrefer(Widget* p)
	{
		if(p->RemoveReference() == 0)
			delete p;
	}
};



class MtRefCountingTraits
{
public:
	void Refer(Widget* p)
	{
		Sentry s(lock_);
		p->AddReference();
	}
	void Unrefer(Widget* p)
	{
		Sentry s(lock_);
		if(p->RemoveReference() == 0)
			delete p;
	}
private:
	Lock lock_;
};